package com.linghang.wusthelper.spider.jwc;

import com.linghang.wusthelper.dao.primary.GradeDao;
import com.linghang.wusthelper.entity.primary.Grade;
import com.linghang.wusthelper.redis.RedisService;
import com.linghang.wusthelper.util.EncryptUtil;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

import java.util.List;


/**
 * @author origin
 * 成绩爬虫
 */
public class GradeSpider implements PageProcessor {

    private GradeDao gradeDao;

    private RedisService redisService;

    private Logger log = LoggerFactory.getLogger(getClass());

    private String lock;

    private Site site = Site.me()
            .setRetryTimes(3)
            .setTimeOut(3000)
            .addHeader("Connection", "keep-alive")
            .addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
            .addHeader("Accept-Encoding", "gzip,deflate,sdch")
            .addHeader("Accept-Language", "zh-CN,zh;q=0.8")
            .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36")
            .addHeader("Cache-Control", "no-cache")
            .addHeader("Host", "jwxt.wust.edu.cn")
            .setDomain("jwxt.wust.edu.cn");

    public GradeSpider(String JSESSIONID, String SERVERID, GradeDao gradeDao,RedisService redisService,String lock) {
        site.addCookie("JSESSIONID", JSESSIONID);
        site.addCookie("SERVERID", SERVERID);
        this.gradeDao = gradeDao;
        this.redisService = redisService;
        this.lock = lock;
    }

    @Override
    public void process(Page page) {
        //  判断请求是否成功
        if (page.getStatusCode() == HttpStatus.SC_OK) {

            String stuNum = page.getHtml().xpath("//*[@id=\"mxh\"]/tbody/tr[1]/td[2]/text()").get();

            Selectable selectable = page.getHtml().xpath("//*[@id=\"mxh\"]/tbody");
            //  获取该学号所有的gradehash
            List<String> gradeHashList = gradeDao.selectHashByStuNum(stuNum);

            List<String> stuNums = selectable.xpath("//tr/td[2]/text()").all();
            List<String> stuNames = selectable.xpath("//tr/td[3]/text()").all();
            List<String> schoolTerms = selectable.xpath("//tr/td[4]/text()").all();
            List<String> courseNames = selectable.xpath("//tr/td[5]/text()").all();
            List<String> grades = selectable.xpath("//tr/td[6]/text()").all();
            List<String> courseNatures = selectable.xpath("//tr/td[8]/text()").all();
            List<String> courseCategorys = selectable.xpath("//tr/td[9]/text()").all();
            List<String> courseHours = selectable.xpath("//tr/td[10]/text()").all();
            List<String> courseCredits = selectable.xpath("//tr/td[11]/text()").all();
            List<String> examNatures = selectable.xpath("//tr/td[12]/text()").all();
            List<String> gradePoints = selectable.xpath("//tr/td[14]/text()").all();
            int size = stuNums.size();
            //  获取每一行的成绩
            for (int i = 0;i < size;i++){
                Grade grade = new Grade();
                grade.setStuNum(stuNums.get(i));
                grade.setStuName(stuNames.get(i));
                grade.setSchoolTerm(schoolTerms.get(i));
                grade.setCourseName(courseNames.get(i));
                grade.setGrade(grades.get(i));
                grade.setCourseNature(courseNatures.get(i));
                grade.setCourseCategory(courseCategorys.get(i));
                grade.setCourseHours(Integer.valueOf(courseHours.get(i)));
                grade.setCourseCredit(Float.valueOf(courseCredits.get(i)));
                grade.setExamNature(examNatures.get(i));
                grade.setGradePoint(Float.valueOf(gradePoints.get(i)));
                grade.setGradeHash(EncryptUtil.getGradeHash(grade));

                //  判断该成绩是否已经存在
                if (gradeHashList.contains(grade.getGradeHash())){
                    //  hsah存在则数据已有此成绩，从List中删除
                    gradeHashList.remove(grade.getGradeHash());
                }else {
                    gradeDao.insert(grade);
                }
            }

            //  hashlist剩余的成绩为作废成绩(老师撤回或因其他原因不可从教务处查询)
            //  作废成绩删除
            for (String s : gradeHashList){
                gradeDao.delInvalid(stuNum,s);
            }
            if (stuNum != null){
                //  将成绩数目存入缓存
                redisService.set(stuNum+":gradenums",String.valueOf(size));
            }
            synchronized (lock){
                lock.notify();
            }
        } else {
            synchronized (lock){
                lock.notify();
            }
            log.error("教务处错误");
        }
    }

    @Override
    public Site getSite() {
        return site;
    }
}
